﻿using Basic.FlowApplication.Model.AuditLog;
using Basic.FlowModel.AuditLogItem;
using Basic.FlowModel.EventTemplate;
using Basic.FlowRemoteModel;
using Basic.FlowRemoteModel.EventTemplate.Model;
using Basic.FlowRemoteModel.FlowAuditInter.Model;
using WeDonekRpc.Client.Collect;
using WeDonekRpc.Helper;
using WeDonekRpc.Helper.Http;
using WeDonekRpc.Helper.IdGenerator;
using WeDonekRpc.Model;

namespace Basic.FlowApplication.AuditLocalEvent
{
    internal static class SendLinq
    {
        public static void Send ( this EventDto ev, AuditItemInfo item, AuditLog log, FlowEventType evType )
        {
            AuditEventBody model = new AuditEventBody
            {
                MsgId = IdentityHelper.CreateId(),
                EventType = evType,
                AppId = log.AppId,
                LinkPk = log.LinkPk,
                LinkType = log.LinkType,
                AuditLog = new AuditLogState
                {
                    AuditStatus = log.AuditStatus,
                    DocTitle = log.DocTitle,
                    Status = log.Status,
                    CompanyId = log.CompanyId,
                    CreateBy = log.CreateBy,
                    CreateByDeptId = log.CreateByDeptId,
                    CreateByUnitId = log.CreateByUnitId,
                    EndTime = log.EndTime,
                    Id = log.Id,
                    ProgressVal = log.ProgressVal
                },
                AuditLogItem = new AuditLogItem
                {
                    EndTime = item.EndTime,
                    EmpByDeptId = item.EmpByDeptId,
                    EmpByUnitId = item.EmpByUnitId,
                    EmpId = item.EmpId,
                    AuditOpinion = item.AuditOpinion,
                    AuditState = item.AuditState,
                    Id = item.Id,
                    Status = item.Status,
                    BatchNo = item.BatchNo,
                    CompanyId = item.CompanyId,
                    SubFlowState = item.SubFlowState
                }
            };
            if ( ev.InterType == FlowInterType.指令 )
            {
                _SendDictate(ev.InterConfig.RpcConfig, model);
            }
            else if ( ev.InterType == FlowInterType.Http )
            {
                _SendHttp(ev.Id, ev.InterConfig.HttpConfig, model);
            }
            else
            {
                _SendBroadcast(ev.InterConfig.BroadcastConfig, model);
            }
        }
        private static void _SendDictate ( RpcParamConfig config, AuditEventBody model )
        {
            IRemoteConfig send = new IRemoteConfig(config.SysDictate, config.TypeVal, config.IsReply, true);
            if ( config.IsEnableLock )
            {
                send.LockType = RemoteLockType.同步锁;
                send.LockColumn = new string[] { "MsgId" };
            }
            if ( config.Transmit.IsNotNull() )
            {
                send.Transmit = config.Transmit;
                send.IdentityColumn = "MsgId";
            }
            if ( !RemoteCollect.Send(send, model, out string error) )
            {
                throw new ErrorException(error);
            }
        }
        private static void _SendHttp ( long evId, HttpInterConfig config, AuditEventBody model )
        {
            string clientKey = "EventInter_" + evId;
            HttpConfig http = config.Config;
            _ = HttpClientFactory.AddClient(clientKey, a =>
            {
                if ( http != null )
                {
                    a.SslProtocols = http.SslProtocols;
                    a.AllowAutoRedirect = http.AllowAutoRedirect;
                    a.AutomaticDecompression = http.AutomaticDecompression;
                    a.MaxAutomaticRedirections = http.MaxAutomaticRedirections;
                }
            });
            string uri = Tools.GetJumpUri(config.Uri, "msgId=" + model.MsgId + "&evType=" + (int)model.EventType);
            using ( HttpClient client = HttpClientFactory.Create(clientKey) )
            {
                _ = client.SendJson(new Uri(uri), model, HttpCompletionOption.ResponseHeadersRead);
            }
        }
        private static void _SendBroadcast ( RpcBroadcastConfig config, AuditEventBody model )
        {
            IRemoteBroadcast send = new IRemoteBroadcast(config.SysDictate, config.IsOnly, config.TypeVal)
            {
                IsCrossGroup = false,
                ServerId = config.ServerId,
                BroadcastType = config.BroadcastType,
                IsExclude = false,
                IsOnly = config.IsOnly
            };
            if ( config.IsEnableLock )
            {
                send.RemoteConfig = new RemoteSet
                {
                    IsEnableLock = true,
                    LockType = RemoteLockType.同步锁,
                    LockColumn = new string[]
                    {
                        "MsgId"
                    }
                };
            }
            RemoteCollect.BroadcastMsg(send, model);
        }
    }
}
